package com.jingsu;

import com.google.common.io.Files;
import com.mrobuy.util.HttpUtils;
import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static org.opencv.core.Core.magnitude;
import static org.opencv.core.CvType.CV_32F;
import static org.opencv.core.CvType.CV_8U;
import static org.opencv.highgui.HighGui.imshow;
import static org.opencv.imgproc.Imgproc.*;

public class MymroInpaint {

    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    private static void inpaint(Mat image, Mat mask) {

        if ( image==null || mask==null ) {
            return;
        }

        int maxRow = image.height();
        int maxCol = image.width();


        for (int row = 0; row < mask.rows(); row++) {

            if ( row >= maxRow ) {
                break;
            }

            for (int col = 0; col < mask.cols(); col++) {

                if ( col >= maxCol ) {
                    break;
                }

                double[] values = image.get(row, col);

                double[] _values = mask.get(row, col);

                if ( values.length >= 3  &&  _values[3] == 72 ) {

                    if (  values[3] == 72 ) {
                        image.put(row, col, 0,0,0,0);
                    } else {
                        for (int i = 0; i < 3; i++) {
                            values[i] = (values[i]*255 - 56*255)/183;
                        }
                        image.put(row, col, values);
                    }

                }
            }
        }
    }

    // 透明图
    public static String lucency(String imagePath) {

        File imageFile = new File(imagePath);
        if ( !imageFile.exists() ) {
            System.err.println("[File: " + imageFile.getAbsolutePath() + "]文件不存在！");
        }

        Mat image = Imgcodecs.imread(imageFile.getAbsolutePath(), Imgcodecs.IMREAD_UNCHANGED);
        System.out.println("channels: " + image.channels() + "; Type:" + image.type());
        if ( image.channels()==3 ) {
            Imgproc.cvtColor(image, image, Imgproc.COLOR_BGR2RGBA);
        }

//        Mat mark = Imgcodecs.imread("watermark.png", Imgcodecs.IMREAD_UNCHANGED);
//
//        inpaint(image, mark);



        Mat src_gray = image.clone();

        Mat detected_edges = new Mat();




        Imgproc.cvtColor(src_gray, src_gray, Imgproc.COLOR_RGBA2GRAY);

        //Imgproc.medianBlur( src_gray, src_gray, 3 );

        Mat dx = new Mat();
        Mat dy = new Mat();
        Mat value = new Mat();
        Sobel(src_gray, dx, CV_32F, 1, 0, 3);
        Sobel(src_gray, dy, CV_32F, 0, 1, 3);
        magnitude(dx, dy, value);

        value.convertTo(value, CV_8U, 1);


        Mat kernel =  getStructuringElement(1, new Size(3, 3));

//        imshow("magnitude", value);
//        HighGui.waitKey(0);


        dilate(value, value, kernel);
        dilate(value, value, kernel);

        erode(value, value, kernel);
        erode(value, value, kernel);
//
//







        equalizeHist( src_gray, src_gray );

        Imgproc.threshold(value, value, 1, 250, THRESH_BINARY);

        imshow(imagePath, value);
        HighGui.waitKey(0);


        Mat image1 = Imgcodecs.imread(imageFile.getAbsolutePath(), Imgcodecs.IMREAD_UNCHANGED);

//        if ( image1.channels()==3 ) {
//            Imgproc.cvtColor(image1, image1, Imgproc.COLOR_BGR2RGBA);
//        }

        int maxRow = image1.height();
        int maxCol = image1.width();


        for (int row = 0; row < value.rows(); row++) {

            if ( row >= maxRow ) {
                break;
            }



            for (int col = 0; col < value.cols(); col++) {

                if ( col >= maxCol ) {
                    break;
                }


                double[] _values = value.get(row, col);

//                if ( values.length == 4 &&  values[3] <= 72 ) {
//                    image.put(row, col, 255, 255, 255, 0);
//                    continue;
//                }

                if ( _values[0] != 0 ) {
                    break;
                }

                image1.put(row, col, 255, 0, 0);
            }

            for (int col = value.cols()-1;  col >= 0; col--) {

                if ( col >= maxCol ) {
                    break;
                }


                double[] _values = value.get(row, col);

//                if ( values.length == 4 &&  values[3] <= 72 ) {
//                    image.put(row, col, 255, 255, 255, 0);
//                    continue;
//                }

                if ( _values[0] != 0 ) {
                    break;
                }

                image1.put(row, col, 255, 0, 0);
            }
        }


        for (int col = 0; col < value.cols(); col++) {
            if ( col >= maxCol ) {
                break;
            }

            for (int row = 0; row < value.rows(); row++) {
                if ( row >= maxRow ) {
                    break;
                }

                double[] _values = value.get(row, col);

                if ( _values[0] != 0 ) {
                    break;
                }

                image1.put(row, col, 255, 0, 0);
            }


            for (int row = value.rows()-1;  row >= 0; row--) {

                if ( row >= maxRow ) {
                    break;
                }


                double[] _values = value.get(row, col);

//                if ( values.length == 4 &&  values[3] <= 72 ) {
//                    image.put(row, col, 255, 255, 255, 0);
//                    continue;
//                }

                if ( _values[0] != 0 ) {
                    break;
                }

                image1.put(row, col, 255, 0, 0);
            }

        }

        imshow(imagePath, image1);
        HighGui.waitKey(0);



        /**
         * 输入参数:
         *
         * detected_edges: 原灰度图像
         * detected_edges: 输出图像 (支持原地计算，可为输入图像)
         * lowThreshold: 用户通过 trackbar设定的值。
         * highThreshold: 设定为低阈值的3倍 (根据Canny算法的推荐)
         * kernel_size: 设定为 3 (Sobel内核大小，内部使用)
         */
        int edgeThresh = 1;
        int lowThreshold = 0;
        int max_lowThreshold = 100;
        int ratio = 3;
        int kernel_size = 3;
        Imgproc.Canny( value, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size );


        /// 寻找轮廓
        List<MatOfPoint> contours = new ArrayList<>();
        Mat hierarchy = new Mat();
        Imgproc.findContours( detected_edges, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE);

        {
//        double maxArea = -1;
//        MatOfPoint maxContour = null;
//        int i = 1;
//        for (MatOfPoint contour : contours) {
//            double curArea = Imgproc.contourArea(contour);
//            if ( maxArea < curArea ) {
//                maxArea = curArea;
//                maxContour = contour;
//            }
//            System.out.println((i++) + ". " + Imgproc.contourArea(contour));
//        }
//
//        Mat drawing = Mat.zeros(detected_edges.size(),  CV_8UC3);
//        Scalar color = new Scalar( 255, 255, 192);
//        Imgproc.drawContours( drawing, Lists.newArrayList(maxContour), 0, color, 2, 8, hierarchy, 0 );

            /// 绘出轮廓
//        Mat drawing = Mat.zeros(detected_edges.size(),  CV_8UC3);
//        for( int j = 0; j < contours.size(); j++ )
//        {
//
//            if ( contours.get(j).toArray().length < 100 ) {
//                for (Point point : contours.get(j).toArray()) {
//                    detected_edges.put((int)point.x, (int)point.y, 0, 0, 0, 0);
//                }
//            }
//
//            //arcLength(contours.get(j),tr);
//
//
//        }
            //Mat kernel = new Mat(new Size(3, 3), CvType.CV_8UC1, new Scalar(255));

        }



        // BackgroundSubtractorMOG2 backgroundSubtractorMOG2 = Video.createBackgroundSubtractorMOG2();

//
        imshow("轮廓", detected_edges);




//
//        Imgproc.bitwise_not(detected_edges, detected_edges, 125, 255 , Imgproc.THRESH_BINARY_INV);

        Core.bitwise_not(detected_edges, detected_edges);
//
        imshow("反色", detected_edges);
//
//        HighGui.waitKey(0);
        HighGui.waitKey(0);




        for (int j = 0; j < 5; j++) {

            //  morphologyEx(detected_edges, detected_edges, MORPH_CLOSE,   kernel);
            erode(detected_edges, detected_edges, kernel);

            dilate(detected_edges, detected_edges, kernel);
        }
//
//        //morphologyEx(detected_edges, detected_edges, MORPH_OPEN,  kernel );
//        for (int j = 0; j < 5; j++) {
//
//          //  morphologyEx(detected_edges, detected_edges, MORPH_CLOSE,   kernel);
//
//        }
//
//        imshow("", detected_edges);
//
//        HighGui.waitKey(0);


        return null;
    }

    public static String inpaint(String imagePath, String outputFile) {
        File imageFile = new File(imagePath);
        if ( !imageFile.exists() ) {
            System.err.println("[File: " + imageFile.getAbsolutePath() + "]文件不存在！");
            return null;
        }


        String fielName = imageFile.getName();

        Mat image = Imgcodecs.imread(imageFile.getAbsolutePath(), Imgcodecs.IMREAD_UNCHANGED);
        int channels = image.channels();
        if ( channels==3 ) {
            Imgproc.cvtColor(image, image, Imgproc.COLOR_BGR2RGBA);
        }

        Mat mark = Imgcodecs.imread("watermark.png", Imgcodecs.IMREAD_UNCHANGED);

        inpaint(image, mark);

        File dest = new File(outputFile);
        if ( !dest.getParentFile().exists() ) {
            dest.mkdirs();
        }

        if ( channels==4 ) {
            File png =  new File(dest.getParent(), Files.getNameWithoutExtension(fielName) + ".png");
            try {
                MatOfInt params = new MatOfInt(Imgcodecs.IMWRITE_PNG_COMPRESSION, 9);
                Imgcodecs.imwrite( png.getAbsolutePath(), image, params);
                Thread.sleep(1000);
                System.out.println("Result: " +  png.renameTo(dest));
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            try {
                Imgproc.cvtColor(image, image, Imgproc.COLOR_BGR2RGB);
                Imgcodecs.imwrite(dest.getAbsolutePath(), image);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return dest.getAbsolutePath();
    }

    public static void main(String[] args) throws IOException {

        File destImageFile = new File(".", "\\target\\product_images_new\\800\\10B\\2018112053.jpg");

        HttpUtils.download("https://static.mymro.cn/product_images_new/800/10B/2018112053.jpg", destImageFile.getAbsolutePath());

        System.out.println(destImageFile.getAbsolutePath());



        String a =  inpaint(destImageFile.getAbsolutePath(), destImageFile.getParent() + File.separator + "out" + File.separator + destImageFile.getName());
        System.out.println(a);

    }

}
